package com.kitbox.hl.meshow.common.utils.system;

import cn.hutool.core.lang.Console;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.UnknownHostException;


public final class NativeUtil {



    public static void main(String[] args) {
      runNativeCommand("calc.exe");

  }

  /****
   * 执行本地命令
   * @param command
   *  * Process的几种方法
   1、destroy()：杀掉子进程
   2、exitValue()：返回子进程的出口值，值0表示正常终止
   3、getErrorStream()：获取子进程的错误流
   4、getInputStream()：获取子进程的输入流
   5、getOutputStream()：获取子进程的输出流
   6、waitFor()：导致当前线程等待，如有必要，一直要等到由该Process对象表示的进程已经终止。如果已终止该子进程，此方法立即返回。如果没有终止该子进程，调用的线程将被阻塞，知道退出子进程，根据管理，0表示正常终止。
   注意：在Java中，调用runtime线程执行脚本是非常消耗资源的，所以切记不要频繁使用！
   在调用runtime去执行脚本的时候，其实就是JVM开了一个子线程去调用JVM所在系统的命令，其中开了三个通道：输入流、输出流、错误流，其中输出流就是子线程走调用的通道。
   */

  public static void runNativeCommand(String command){

    try {
      Process process = Runtime.getRuntime().exec(command);
      InputStream in = process.getInputStream();
      while (in.read() != -1) {
        System.out.println(in.read());
      }
      in.close();
      process.waitFor();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }


  /** 获取网卡序列号 */
  public static final String getDUID() {
    String address = "";
    String command = "cmd.exe /c ipconfig /all";
    try {
      Process p = Runtime.getRuntime().exec(command);
      BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
      String line;
      while ((line = br.readLine()) != null) {
        if (line.indexOf("DUID") > 0) {
          int index = line.indexOf(":");
          index += 2;
          address = line.substring(index);
          break;
        }
      }
      br.close();
    } catch (IOException e) {}
    return address;
  }

  /**
   * 查看指定的端口号是否空闲，若空闲则返回否则返回一个随机的空闲端口号
   */
  public static int getFreePort(int defaultPort) throws IOException {
    try (
            ServerSocket serverSocket = new ServerSocket(defaultPort)
    ) {
      return serverSocket.getLocalPort();
    } catch (IOException e) {
      return getFreePort();
    }
  }

  /**
   * 获取空闲端口号
   */
  public static int getFreePort() throws IOException {
    try (
            ServerSocket serverSocket = new ServerSocket(0)
    ) {
      return serverSocket.getLocalPort();
    }
  }

  /**
   * 检查端口号是否被占用
   */
  public static boolean isBusyPort(int port) {
    boolean ret = true;
    ServerSocket serverSocket = null;
    try {
      serverSocket = new ServerSocket(port);
      ret = false;
    } catch (Exception e) {
    } finally {
      if (serverSocket != null) {
        try {
          serverSocket.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    return ret;
  }


}





























